﻿// ———————————————————————–
// <copyright file="SettingsForm.cs" company="The MITRE Corporation">
//    Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// SettingsForm.cs - Settings Winform for the EDXL Debug Tool
// Project: IC.NET - EDXL Test App
//
// Language:    C#, .NET 4.0
// Platform:    Windows 7, VS 2010 Beta 2
// Author:      Don McGarry MITRE Rome

// Author:      Joseph Whitmore, Bedford

/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)

using System;
using System.Collections.Generic;
using System.Windows.Forms;

using EDXLSharp.EDXLDELib;

namespace EDXLSharp.EDXLTestApplication
{
  /// <summary>
  /// Class representing the TestApp Settings Form
  /// </summary>
  public partial class SettingsForm : Form
  {
    /// <summary>
    /// Define TestAppSettings objects
    /// </summary>
    private TestAppSettings settingsTemp, settingsTempPtr;

    /// <summary>
    /// Define mSettingTempFile string
    /// </summary>
    private string settingsTempFile;

    /// <summary>
    /// Define OnSettingChange callback method pointer
    /// </summary>
    private OnSettingsChange settingsCallBack;
    
    /// <summary>
    /// Initializes a new instance of the SettingsForm class
    /// Default Ctor
    /// </summary>
    public SettingsForm()
    {
      this.InitializeComponent();
      List<string> enumTemp = new List<string>(Enum.GetNames(typeof(StatusValue)));

      // Add Enum Values to ComboBoxes
      foreach (string s in enumTemp)
      {
        this.mComboDistStatusDefault.Items.Add(s);
      }

      enumTemp = new List<string>(Enum.GetNames(typeof(TypeValue)));
      foreach (string s in enumTemp)
      {
        this.mComboDistTypeDefault.Items.Add(s);
      }
    }

    /// <summary>
    /// Initializes a new instance of the SettingsForm class
    /// Ctor That Takes Settings Object
    /// </summary>
    /// <param name="settings">Settings Objet</param>
    /// <param name="settingsFile">Path + Name of the Settings File</param>
    public SettingsForm(TestAppSettings settings, string settingsFile)
    {
      this.InitializeComponent();
      List<string> enumTemp = new List<string>(Enum.GetNames(typeof(StatusValue)));

      // Add Enum Values to ComboBoxes
      foreach (string s in enumTemp)
      {
        this.mComboDistStatusDefault.Items.Add(s);
      }

      enumTemp = new List<string>(Enum.GetNames(typeof(TypeValue)));
      foreach (string s in enumTemp)
      {
        this.mComboDistTypeDefault.Items.Add(s);
      }

      this.settingsTempPtr = settings;
      this.settingsTemp = new TestAppSettings(this.settingsTempPtr);
      this.settingsTempFile = settingsFile;
      this.InitializeFormValues();
    }

    /// <summary>
    /// Define OnSettingChange method
    /// </summary>
    /// <param name="Settings">Setting to be modified</param>
    public delegate void OnSettingsChange(TestAppSettings Settings);
    
    /// <summary>
    /// Gets or sets
    /// Accessor for OnSettings change property
    /// </summary>
    public OnSettingsChange SettingsCallBack
    {
      get { return this.settingsCallBack; }
      set { this.settingsCallBack = value; }
    }

    /// <summary>
    /// Gets or sets
    /// </summary>
    public TestAppSettings MTestAppSettings
    {
      get { return this.settingsTemp; }
      set { this.settingsTemp = value; }
    }

    /// <summary>
    /// Cancel Button
    /// </summary>
    /// <param name="sender">Object generating the event</param>
    /// <param name="e">event generated by the object</param>
    private void MButtCancelmButtCancel_Click(object sender, EventArgs e)
    {
      this.Close();
    }

    /// <summary>
    /// Save the setting from the settings form
    /// </summary>
    /// <param name="sender">object generating the event</param>
    /// <param name="e">event generated by the object</param>
    private void MButtSave_Click(object sender, EventArgs e)
    {
      if (this.GetSettingsValues())
      {
        this.settingsTempPtr = this.settingsTemp;
        this.settingsTempPtr.Save(this.settingsTempFile);
        this.SettingsCallBack.Invoke(this.settingsTempPtr);
      }

      this.Close();
    }

    /// <summary>
    /// Apply changes from the settings forms
    /// </summary>
    /// <param name="sender">object generating the event</param>
    /// <param name="e">event generated by the object</param>
    private void MButtApply_Click(object sender, EventArgs e)
    {
      if (this.GetSettingsValues())
      {
        this.settingsTempPtr = new TestAppSettings(this.settingsTemp);
        this.SettingsCallBack.Invoke(this.settingsTempPtr);
      }

      this.Close();
    }

    /// <summary>
    /// Load Setting form with TestApp Settings
    /// </summary>
    private void InitializeFormValues()
    {
      this.mTextLogFile.Text = this.settingsTemp.LogFile;
      this.mTextMaxLogSize.Text = this.settingsTemp.MaxLogLength.ToString();
      this.mTextPeriod.Text = this.settingsTemp.Period.ToString();
      this.mCheckKeepTxOpen.Checked = this.settingsTemp.TxSocketStayOpen;
      this.mTextHistoryLength.Text = this.settingsTemp.HistoryLength.ToString();
      this.mTextDistributionPrefix.Text = this.settingsTemp.DistributionPrefix;
      this.mTextSenderDefault.Text = this.settingsTemp.SenderDefault;
      this.mComboDistStatusDefault.Text = this.settingsTemp.DistStatusDefault.ToString();
      this.mComboDistTypeDefault.Text = this.settingsTemp.DistTypeDefault.ToString();
      this.mTextConfDefault.Text = this.settingsTemp.ConfDefault;
      this.mCheckTCPSend.Checked = this.settingsTemp.TCPSend;
      this.mCheckTCPRecieve.Checked = this.settingsTemp.TCPRecv;
      this.mCheckUDPSend.Checked = this.settingsTemp.UDPSend;
      this.mCheckUDPRecieve.Checked = this.settingsTemp.UDPRecv;
      this.mTextTCPSendHost.Text = this.settingsTemp.TCPDestHost;
      this.mTextTCPSendPort.Text = this.settingsTemp.TCPDestPort.ToString();
      this.mTextTCPRecievePort.Text = this.settingsTemp.TCPListenPort.ToString();
      this.mTextUDPSendHost.Text = this.settingsTemp.UDPDestHost;
      this.mTextUDPSendPort.Text = this.settingsTemp.UDPDestPort.ToString();
      this.mTextUDPRecievePort.Text = this.settingsTemp.UDPListenPort.ToString();
    }

    /// <summary>
    /// Loads the TestApp settings
    /// </summary>
    /// <returns>bool value = true if setting load successfully, else false</returns>
    private bool GetSettingsValues()
    {
      this.settingsTemp.LogFile = this.mTextLogFile.Text;
      try
      {
        this.settingsTemp.MaxLogLength = uint.Parse(this.mTextMaxLogSize.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For Max Log Length!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }
      
      try
      {
        this.settingsTemp.Period = Int32.Parse(this.mTextPeriod.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For Period!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      this.settingsTemp.TxSocketStayOpen = this.mCheckKeepTxOpen.Checked;
      try
      {
        this.settingsTemp.HistoryLength = uint.Parse(this.mTextHistoryLength.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For History Length!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      this.settingsTemp.DistributionPrefix = this.mTextDistributionPrefix.Text;
      this.settingsTemp.SenderDefault = this.mTextSenderDefault.Text;
      try
      {
        this.settingsTemp.DistStatusDefault = (StatusValue)Enum.Parse(typeof(StatusValue), this.mComboDistStatusDefault.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For Status Value!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }
      
      try
      {
        this.settingsTemp.DistTypeDefault = (TypeValue)Enum.Parse(typeof(TypeValue), this.mComboDistTypeDefault.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For Type Value!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      this.settingsTemp.ConfDefault = this.mTextConfDefault.Text;
      this.settingsTemp.TCPSend = this.mCheckTCPSend.Checked;
      this.settingsTemp.TCPRecv = this.mCheckTCPRecieve.Checked;
      this.settingsTemp.UDPSend = this.mCheckUDPSend.Checked;
      this.settingsTemp.UDPRecv = this.mCheckUDPRecieve.Checked;
      this.settingsTemp.TCPDestHost = this.mTextTCPSendHost.Text;
      try
      {
        this.settingsTemp.TCPDestPort = Int32.Parse(this.mTextTCPSendPort.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For TCP Send Port!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      try
      {
        this.settingsTemp.TCPListenPort = Int32.Parse(this.mTextTCPRecievePort.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For TCP Recieve Port!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      this.settingsTemp.UDPDestHost = this.mTextUDPSendHost.Text;
      try
      {
        this.settingsTemp.UDPDestPort = Int32.Parse(this.mTextUDPSendPort.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For UDP Send Port!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      try
      {
        this.settingsTemp.UDPListenPort = Int32.Parse(this.mTextUDPRecievePort.Text);
      }
      catch (Exception e)
      {
        MessageBox.Show("Invalid Value For UDP Recieve Port!\n" + e.ToString(), "IO Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return false;
      }

      return true;
    }
  }
}
